import i18n from '../../../i18n';
/**
 * 是否有人已经报名了比赛
 */
let raceEnterStat: boolean = false;
/**
 * 比赛是否开始
 */
let racestat: boolean = false;
/**
 * 报名比赛的玩家
 */
let enterPerson: GameEntity[] = [];
/**
 * 到达终点的玩家
 */
let arrivePerson: GameEntity[] = [];
/**
 * @description 报名比赛的模块
 */
class EnterModule {
  static async enterRace(entity: GamePlayerEntity) {
    if (racestat) {
      entity.player.directMessage(
        i18n.t('enter.failed_race', { lng: entity.language })
      );
      return;
    }
    if (entity.hasTag('enter_for_game')) {
      entity.player.directMessage(
        i18n.t('enter.failed_hasEnter', { lng: entity.language })
      );
      return;
    }
    if (entity.haspassed) {
      if (raceEnterStat) {
        entity.addTag('enter_for_game');
        entity.player.directMessage(
          i18n.t('enter.success', { lng: entity.language })
        );
        enterPerson.push(entity);
      } else {
        entity.player.directMessage(
          i18n.t('enter.success', { lng: entity.language })
        );
        raceEnterStat = true;
        entity.addTag('enter_for_game');
        enterPerson = [entity];
        let time = 20;
        while (time) {
          await sleep(1000);
          time--;
          world.querySelectorAll('player').forEach((x) => {
            x.player.directMessage(
              i18n.t('enter.time', { time, lng: (x as GameEntity).language })
            );
          });
        }
        racestat = true;
        arrivePerson = [];
        world
          .querySelectorAll('player')
          .filter((x) => x.hasTag('enter_for_game'))
          .forEach((x) => {
            x.position.set(237.5, 24, 237.5);
            x.player.disableInputDirection = GameInputDirection.BOTH;
            x.player.walkSpeed = x.player.runSpeed = x.useCar.speed;
            x.player.walkAcceleration = x.player.runAcceleration =
              x.useCar.acceleration;
            x.player.jumpPower = x.useCar.jumpPower;
            x.player.invisible = true;
            x.meshScale = new GameVector3(0.03, 0.03, 0.03);
            x.player.enableJump = false;
            console.log(x.useCar.id);
            x.mesh = `mesh/${x.useCar.id}.vb` as GameModelAssets;
            x.player.directMessage(
              i18n.t('race.start', { lng: (x as GameEntity).language })
            );
          });
        time = 5;
        while (time) {
          await sleep(1000);
          time--;
          world.querySelectorAll('player').forEach((x) => {
            x.player.directMessage(
              i18n.t('race.countdown', {
                time,
                lng: (x as GameEntity).language,
              })
            );
          });
        }
        world
          .querySelectorAll('player')
          .filter((x) => x.hasTag('enter_for_game'))
          .forEach((x) => {
            x.player.enableJump = true;
            x.player.directMessage(
              i18n.t('race.start', { lng: (x as GameEntity).language })
            );
            x.addTag('ingame');
            x.player.disableInputDirection = GameInputDirection.NONE;
            x.startTime = Date.now();
          });
        let lastTime = 200;
        while (lastTime) {
          await sleep(1000);
          lastTime--;
          if (arrivePerson.length >= enterPerson.length) {
            racestat = false;
            break;
          }
        }
        racestat = false;
        world.querySelectorAll('player').forEach((x) => {
          if (x.hasTag('enter_for_game')) {
            x.player.forceRespawn();
            x.mesh = '';
            x.player.invisible = false;
            x.player.walkSpeed = x.player.runSpeed = 0.3994140625;
            x.player.walkAcceleration = x.player.runAcceleration = 0.349609375;
            x.player.disableInputDirection = GameInputDirection.NONE;
            x.removeTag('ingame');
            x.player.jumpPower = 0.9559609375;
            x.removeTag('enter_for_game');
            x.player.directMessage(i18n.t('race.end', { lng: x.language }));
          }
        });
        raceEnterStat = false;
        racestat = false;
        enterPerson = [];
        arrivePerson = [];
      }
    } else {
      entity.player.directMessage(
        i18n.t('enter.failed_exam', { lng: entity.language })
      );
    }
  }
}

const race_interact = world.querySelector('#游戏报名点') as GameEntity;
race_interact.enableInteract = true;
race_interact.interactRadius = 5;
race_interact.onInteract(async ({ entity }) => {
  EnterModule.enterRace(entity as GamePlayerEntity);
});
world.onEntityContact(({ entity, other }) => {
  if (other.player) {
    if (entity.id === '终点') {
      if (other.hasTag('enter_for_game')) {
        arrivePerson.push(other as GameEntity);
        if (arrivePerson.length === 1) {
          other.position.set(212.5, 7, 181.5);
        } else if (arrivePerson.length === 2) {
          other.position.set(212.5, 6, 185.5);
        } else if (arrivePerson.length === 3) {
          other.position.set(212.5, 5, 177.5);
        } else {
          other.position.set(219, 2, 181.5);
        }
        other.player.disableInputDirection = GameInputDirection.BOTH;
        if (other.fastestRecord > (Date.now() - other.startTime) / 1000) {
          other.fastestRecord = (Date.now() - other.startTime) / 1000;
          other.player.directMessage(
            i18n.t('race.fastest_record', {
              speed: other.fastestRecord.toFixed(2),
              lng: (other as GameEntity).language,
            })
          );
        }
        other.player.dialog<GameTextDialogParams>({
          type: GameDialogType.TEXT,
          content: i18n.t('race.end_content', {
            number: arrivePerson.length,
            speed: ((Date.now() - other.startTime) / 1000).toFixed(2),
            money:
              (500 -
                Math.round(
                  Number(((Date.now() - other.startTime) / 1000).toFixed(2))
                )) *
              2,
            lng: (other as GameEntity).language,
          }),
        });
        other.coin +=
          (500 -
            Math.round(
              Number(((Date.now() - other.startTime) / 1000).toFixed(2))
            )) *
          2;
        other.exp +=
          (500 -
            Math.round(
              Number(((Date.now() - other.startTime) / 1000).toFixed(2))
            )) *
          4;
        while (other.exp >= other.level * 20) {
          other.level++;
          other.exp -= other.level * 20;
          world.querySelectorAll('player').forEach((x) => {
            x.player.directMessage(
              i18n.t('common.level_up', {
                name: other.player?.name,
                level: other.level,
                lng: (x as GameEntity).language,
              })
            );
          });
        }
        world.querySelectorAll('player').forEach((x) => {
          x.player.directMessage(
            i18n.t('race.end_message', {
              name: other.player?.name,
              number: arrivePerson.length,
              speed: ((Date.now() - other.startTime) / 1000).toFixed(2),
              lng: (x as GameEntity).language,
            })
          );
        });
      }
    }
  }
});
